﻿using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Streambolics.Lcars
{
    /// <summary>
    ///     A component that synchronizes all animations for panels on the form.
    /// </summary>

    public class Choreographer : Timer
    {
        private int _MaxConcurrentPanels = 1;
        private int _MaxConcurrentAnimations = 1;
        private List<Panel> _Panels = new List<Panel> ();

        public Choreographer ()
        {
            InitializeComponent ();
        }

        public Choreographer (IContainer container)
        {
            container.Add (this);
            InitializeComponent ();
        }

        private void InitializeComponent ()
        {
            Interval = 100;
        }

        public int MaxConcurrentPanels
        {
            get
            {
                return _MaxConcurrentPanels;
            }
            set
            {
                _MaxConcurrentPanels = value;
            }
        }

        public int MaxConcurrentAnimations
        {
            get
            {
                return _MaxConcurrentAnimations;
            }
            set
            {
                _MaxConcurrentAnimations = value;
            }
        }
        /// <summary>
        ///     Enqueues a panel for animation.
        /// </summary>
        /// <param name="aPanel">
        ///     The panel to enqueue.
        /// </param>
        /// <remarks><para>
        ///     If the panel to enqueue was already enqueued, it is put back at the
        ///     end of the queue.
        /// </para></remarks>

        internal void Enqueue (Panel aPanel)
        {
            _Panels.Remove (aPanel);
            _Panels.Add (aPanel);
            EnableDisable ();
        }

        private void Animate ()
        {
            int i = 0;
            int RemainingPanels = _MaxConcurrentPanels;
            int RemainingAnimations = _MaxConcurrentAnimations;
            while (i < _Panels.Count && RemainingPanels-- > 0 && RemainingAnimations > 0)
            {
                int n = _Panels[i].Animate ();
                if (n <= 0)
                {
                    _Panels.RemoveAt (i);
                }
                else
                {
                    i++;
                    RemainingAnimations -= n;
                }
            }
            EnableDisable ();
        }

        private void EnableDisable ()
        {
            Enabled = _Panels.Count > 0;
        }

        protected override void OnTick (System.EventArgs e)
        {
            base.OnTick (e);
            Animate ();
        }
    }
}
